package com.tengju.user.infrastructure.repository.convert;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.tengju.user.domain.model.archive.resume.*;
import com.tengju.user.domain.model.user.UserId;
import com.tengju.user.domain.shared.IdObject;
import com.tengju.user.domain.shared.JsonMap;
import com.tengju.user.domain.shared.JsonUtil;
import com.tengju.user.infrastructure.persistence.mybatis.dataobject.ArchiveResumeDO;
import org.apache.commons.lang3.StringUtils;

import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

public class ResumeConvert {

    private ResumeConvert() {
    }

    public static Resume doToModel(ArchiveResumeDO resumeDO) {
        if (resumeDO == null) {
            return null;
        }
        return new Resume(
                new ResumeId(resumeDO.getResumeId()),
                new UserId(resumeDO.getUserId()),
                Optional.ofNullable(resumeDO.getBrandIds())
                        .filter(StringUtils::isNotBlank)
                        .map(json -> {
                            try {
                                JSONArray list = JSON.parseArray(json);
                                return new HashSet<>(list.toJavaList(Long.class));
                            } catch (Exception e) {
                                return new HashSet<Long>();
                            }
                        })
                        .map(set -> set.stream().map(BrandId::new).collect(Collectors.toList()))
                        .orElse(null),
                Optional.ofNullable(resumeDO.getSelfMedia())
                        .filter(StringUtils::isNotBlank)
                        .map(json -> {
                            try {
                                return JsonUtil.toMap(json);
                            } catch (Exception e) {
                                return null;
                            }
                        })
                        .map((Function<Map<String, String>, JsonMap<SelfMediaType>>) JsonMap::new)
                        .orElse(null),
                Optional.ofNullable(resumeDO.getCommunity())
                        .filter(StringUtils::isNotBlank)
                        .map(json -> {
                            try {
                                return JSON.parseObject(json, CommunityInfo.class);
                            } catch (Exception e) {
                                return null;
                            }
                        })
                        .orElse(null),
                Optional.ofNullable(resumeDO.getCompanyInfo())
                        .filter(StringUtils::isNotBlank)
                        .map(json -> {
                            try {
                                return JSON.parseObject(json, CompanyInfo.class);
                            } catch (Exception e) {
                                return null;
                            }
                        })
                        .orElse(null),
                resumeDO.getChannelExperience(),
                resumeDO.getCreateTime()
        );
    }

    public static ArchiveResumeDO modelToDo(Resume resume) {
        if (resume == null) {
            return null;
        }
        return ArchiveResumeDO.builder()
                .resumeId(resume.getResumeId().getValue())
                .userId(resume.getUserId().getValue())
                .brandIds(Optional.ofNullable(resume.getBrandIds())
                        .map(brandIds -> brandIds.stream()
                                .map(IdObject::toString)
                                .collect(Collectors.toList()))
                        .map(JsonUtil::toJSONString)
                        .orElse("[]")
                )
                .selfMedia(Optional.ofNullable(resume.getSelfMedia())
                        .map(JSON::toJSONString)
                        .orElse("{}")
                )
                .community(Optional.ofNullable(resume.getCommunity())
                        .map(JSON::toJSONString)
                        .orElse("{}")
                )
                .companyInfo(Optional.ofNullable(resume.getCompany())
                        .map(JSON::toJSONString)
                        .orElse("{}")
                )
                .channelExperience(resume.getChannelExperience())
                .extra("{}")
                .build();
    }

}
